package com.bwie.service.impl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.pojo.TbMenu;
import com.bwie.pojo.TbUser;
import com.bwie.service.TbUserService;
import com.bwie.mapper.TbUserMapper;
import com.bwie.utils.MD5Utils;
import com.bwie.utils.R;
import com.bwie.utils.TokenUtils;
import com.bwie.vo.LoginVo;
import com.bwie.vo.PageInfoVo;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
* @author andy
* @description 针对表【tb_user(用户表)】的数据库操作Service实现
* @createDate 2025-06-19 13:55:50
*/
@Service
public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser>
    implements TbUserService{

    @Autowired
    HttpServletRequest request;

    @Autowired
    TbUserMapper tbUserMapper;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    RestHighLevelClient restHighLevelClient;

    @Override
    public R login(LoginVo loginVo) {
        //--1 判断用户是否存在
        TbUser tbUser = tbUserMapper.selectOne(
                new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserName, loginVo.getUserName())
        );
        if(tbUser == null) {
            return R.error().setMsg("用户不存在");
        }

        //--2 验证密码
        String encrypt = MD5Utils.encrypt(loginVo.getUserPass());
        System.out.println("加密的密码:"+encrypt);
        if(!tbUser.getUserPass().equals(encrypt)) {
            return R.error().setMsg("密码错误");
        }


        //--3 生成token
        String token = Jwts.builder()
                .signWith(SignatureAlgorithm.HS256, "123456")
                .claim("userId", tbUser.getUserId())
                .claim("userName", tbUser.getUserName())
                .compact();


        //--4 token存入redis，并设置过期时间
        String key = "token-" + tbUser.getUserId();
        stringRedisTemplate.opsForValue().set(key, token, 60, TimeUnit.MINUTES);

        //--5 返回token和用户信息
        tbUser.setToken(token);

        return R.ok().setData(tbUser);
    }

    @Override
    public R getMenuTree() {
        //--0 从token中解析出来userId
        String token = request.getHeader("token");
        if(token == null) {
            return R.error().setMsg("请先登录");
        }
        Integer userId = TokenUtils.getUserId(token);

        //--1 根据用户ID获取权限列表
        List<TbMenu> menuList = tbUserMapper.getMenuListByUserId(userId);

        //--2 把用户的权限列表封装到菜单树
        List<Tree<String>> menuTree = TreeUtil.build(menuList, "0", (menu, treeNode) -> {
            treeNode.setName(menu.getMenuName());
            treeNode.setId(menu.getMenuId().toString());
            treeNode.setParentId(menu.getMenuPid().toString());
            treeNode.putExtra("path", menu.getMenuPath());
        });

        return R.ok().setData(menuTree);
    }

    @Override
    public R getUserList(PageInfoVo pageInfoVo) {
        //--1 构造分页参数
        Page<TbUser> page = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());

        //--2 获取用户列表
        QueryWrapper<TbUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().orderByDesc(TbUser::getCreateTime);
        Page<TbUser> tbUserPage = tbUserMapper.selectPage(page, wrapper);

        //--3 返回用户列表
        return R.ok().setData(tbUserPage);
    }

    @Override
    public R getUserInfo() {
        //--1 获取token，获取用户ID
        String token = request.getHeader("token");
        if(token == null) {
            return R.error().setMsg("请先登录");
        }

        //--2 根据用户ID获取用户信息
        Integer userId = TokenUtils.getUserId(token);
        TbUser tbUser = tbUserMapper.selectById(userId);

        //--3 根据用户ID，获取用的角色
        List<String> roleNames = tbUserMapper.getRoleNameByUserId(userId);
//        tbUser.setRoleNames(JSON.toJSONString(roleNames));
        StringBuilder stringBuilder = new StringBuilder();
        for (String roleName : roleNames) {
            if(stringBuilder.length() > 0) {
                stringBuilder.append( ",").append(roleName);
            }
            else {
                stringBuilder.append(roleName);
            }
        }
        tbUser.setRoleNames(stringBuilder.toString());

        //--4 根据用户ID，获取用户的权限列表


        // 脱敏
        tbUser.setUserPass( null);
        tbUser.setToken(token);

        return R.ok().setData(tbUser);
    }

    @Override
    public R getUserInfoById(Integer userId) {
        //--2 根据用户ID获取用户信息
        TbUser tbUser = tbUserMapper.selectById(userId);
        if(tbUser == null) {
            return R.error().setMsg("用户不存在");
        }
        // 脱敏
        tbUser.setUserPass( null);

        return R.ok().setData(tbUser);
    }

    @Override
    public R createIndex() {

        try {
            CreateIndexRequest createIndexRequest = new CreateIndexRequest("es_user");

            createIndexRequest.source("", XContentType.JSON);

            CreateIndexResponse response = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);

            boolean acknowledged = response.isAcknowledged();
            if(acknowledged) {
                return R.ok().setMsg("创建索引成功");
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return R.error().setMsg("创建索引失败");
    }

    @Override
    public R signIn() {
        //--1 获取token，获取用户ID，获取用户信息
        String token = request.getHeader("token");
        if(token == null) {
            return R.error().setMsg("请先登录");
        }
        Integer userId = TokenUtils.getUserId(token);
        TbUser tbUser = tbUserMapper.selectById(userId);
        if(tbUser == null) {
            return R.error().setMsg("用户不存在");
        }

        //--2 签到送积分
        int score = RandomUtil.randomInt(10, 100);
        tbUser.setUserScore(tbUser.getUserScore() + score);
        // 签到送的积分更新到数据库
        tbUserMapper.updateById(tbUser);

        return R.ok().setMsg("签到成功，赠送 "+score + "积分").setData(tbUser);
    }

    @Override
    public R joinActiveSubScore(Integer userId, Integer score) {
        //--1 获取用户信息
        TbUser tbUser = tbUserMapper.selectById(userId);
        if(tbUser == null) {
            return R.error().setMsg("用户不存在");
        }

        //--2 减积分
        if(tbUser.getUserScore() < score) {
            return R.error().setMsg("积分不足");
        }
        tbUser.setUserScore(tbUser.getUserScore() - score);
        tbUserMapper.updateById(tbUser);

        return R.ok();
    }
}




